package top.yvyan.guettable.fragment;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.zhuangfei.timetable.model.Schedule;
import com.zhuangfei.timetable.model.ScheduleSupport;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import top.yvyan.guettable.MainActivity;
import top.yvyan.guettable.R;
import top.yvyan.guettable.adapter.DayClassAdapter;
import top.yvyan.guettable.bean.CourseBean;
import top.yvyan.guettable.bean.ExamBean;
import top.yvyan.guettable.data.AccountData;
import top.yvyan.guettable.data.GeneralData;
import top.yvyan.guettable.data.ScheduleData;
import top.yvyan.guettable.data.SettingData;
import top.yvyan.guettable.data.SingleSettingData;
import top.yvyan.guettable.data.TokenData;
import top.yvyan.guettable.moreFun.ExamActivity;
import top.yvyan.guettable.moreFun.ExamScoreNewActivity;
import top.yvyan.guettable.moreFun.GradesActivity;
import top.yvyan.guettable.service.AutoUpdate;
import top.yvyan.guettable.service.CommFunc;
import top.yvyan.guettable.util.AppUtil;
import top.yvyan.guettable.util.BackgroundUtil;
import top.yvyan.guettable.util.CourseUtil;
import top.yvyan.guettable.util.TimeUtil;
import top.yvyan.guettable.util.ToastUtil;

public class DayClassFragment extends Fragment implements View.OnClickListener {

  private View view;

  private TextView textView;
  private RecyclerView recyclerView;
  private View showExam;
  private TextView showExamDay;
  private TextView networkType;
  private TextView lastSync;
  private TextView tools_networkType;
  private TextView tools_lastSync;
  private AutoUpdate autoUpdate;

  private SingleSettingData singleSettingData;
  private AccountData accountData;
  private GeneralData generalData;
  private SettingData settingData;

  private CourseTableFragment courseTableFragment;

  public static DayClassFragment newInstance() {
    return new DayClassFragment();
  }

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initData();
    DayClassHandler handler = new DayClassHandler(Looper.getMainLooper(), new WeakReference<>(this));
    handler.sendEmptyMessageDelayed(1, 60000);
  }

  @Override
  public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && ScheduleData.isUpdate()) {
      onStart();
      ScheduleData.setUpdate(false);
    }
  }

  public void setCourseTableFragment(CourseTableFragment courseTableFragment) {
    this.courseTableFragment = courseTableFragment;
    if (autoUpdate != null) {
      autoUpdate.setCourseTableFragment(courseTableFragment);
    }
  }

  private boolean isShowTools;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_day_class, container, false);
    View tools = view.findViewById(R.id.day_class_tools);
    isShowTools = SettingData.newInstance(getContext()).isShowTools();
    if (!isShowTools || !(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)) {
      tools.setVisibility(View.GONE);
    }
    initData();
    View addStatus = view.findViewById(R.id.add_status);
    ViewGroup.LayoutParams lp = addStatus.getLayoutParams();
    lp.height = lp.height + AppUtil.getStatusBarHeight(requireContext());
    addStatus.setLayoutParams(lp);

    textView = view.findViewById(R.id.day_class_hint);
    textView.setOnClickListener(this);
    showExam = view.findViewById(R.id.day_show_exam);
    showExamDay = view.findViewById(R.id.day_show_exam_day);
    View testSchedule = view.findViewById(R.id.day_test_schedule);
    testSchedule.setOnClickListener(this);
    View urlBkjw = view.findViewById(R.id.day_url_bkjwtest);
    urlBkjw.setOnClickListener(this);
    View testScores = view.findViewById(R.id.day_test_scores);
    testScores.setOnClickListener(this);
    View credits = view.findViewById(R.id.day_credits);
    credits.setOnClickListener(this);
    networkType = view.findViewById(R.id.networkType);
    lastSync = view.findViewById(R.id.lastSync);
    tools_networkType = view.findViewById(R.id.day_class_tools_network_type);
    tools_lastSync = view.findViewById(R.id.day_class_tools_lastsync);
    updateNetworkType();
    updateLastSync();
    autoUpdate = new AutoUpdate(this);
    if (courseTableFragment != null) {
      autoUpdate.setCourseTableFragment(courseTableFragment);
    }
    if (accountData.getIsLogin()) {
      autoUpdate.start();
    }
    recyclerView = view.findViewById(R.id.day_class_detail_recycleView);
    return view;
  }

  private void initData() {
    singleSettingData = SingleSettingData.newInstance(getActivity());
    accountData = AccountData.newInstance(getActivity());
    generalData = GeneralData.newInstance(getActivity());
    settingData = SettingData.newInstance(getActivity());
  }

  public void updateNetworkType() {
    if (isShowTools) {
      if (networkType != null) networkType.setVisibility(View.GONE);
      if (tools_networkType != null) {
        if (TokenData.networkType == null) {
          tools_networkType.setText("未知");
        } else {
          switch (TokenData.networkType) {
            case WVPN:
              tools_networkType.setText("WebApp VPN");
              break;
            case CampusNetwork:
              tools_networkType.setText("校园网");
              break;
            case VPN:
              tools_networkType.setText("WebVPN");
              break;
          }
        }
      }
    } else if (networkType != null) {
      if (TokenData.networkType == null) {
        networkType.setText("当前网络环境：未知，同步后更新");
      } else {
        switch (TokenData.networkType) {
          case WVPN:
            networkType.setText("上次同步网络环境: WebApp VPN");
            break;
          case CampusNetwork:
            networkType.setText("上次同步网络环境: 校园网");
            break;
          case VPN:
            networkType.setText("上次同步网络环境: WebVPN");
            break;
        }
      }
      networkType.setVisibility(View.VISIBLE);
    }
  }

  public void updateLastSync() {
    CharSequence lastSyncString = DateUtils.getRelativeTimeSpanString(generalData.getLastUpdateTime(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS);
    if (isShowTools) {
      if (lastSync != null) lastSync.setVisibility(View.GONE);
      if (tools_lastSync != null) {
        tools_lastSync.setText(lastSyncString);
      }
    } else if (lastSync != null) {
      lastSync.setText("上次同步时间: " + lastSyncString);
      lastSync.setVisibility(View.VISIBLE);
    }
  }

  public DayClassAdapter dayClassAdapter;

  /**
   * 更新日课表视图
   */
  @SuppressLint({"SetTextI18n", "NotifyDataSetChanged"})
  public void updateView() {
    updateNetworkType();
    updateLastSync();
    List<Schedule> allClass = getData();
    List<Schedule> todayList = new ArrayList<>(), tomorrowList = new ArrayList<>();
    if (!allClass.isEmpty()) {
      todayList = ScheduleSupport.getHaveSubjectsWithDay(
              allClass,
              generalData.getWeek(true),
              TimeUtil.getDay()
      );
      tomorrowList = ScheduleSupport.getHaveSubjectsWithDay(
              allClass,
              TimeUtil.getNextDayWeek(generalData.getWeek(true)),
              TimeUtil.getNextDay()
      );
    }
    Collections.sort(todayList, (Schedule a, Schedule b) -> {
      return (a.getStart() - b.getStart()) * 100000 + allClass.indexOf(a) - allClass.indexOf(b);
    });
    Collections.sort(tomorrowList, (Schedule a, Schedule b) -> {
      return (a.getStart() - b.getStart()) * 100000 + allClass.indexOf(a) - allClass.indexOf(b);
    });
    if (recyclerView == null) {
      return;
    }
    if (dayClassAdapter == null) {
      dayClassAdapter = new DayClassAdapter(getContext(), todayList, tomorrowList);
    } else {
      dayClassAdapter.todayList = todayList;
      dayClassAdapter.tomorrowList = tomorrowList;
    }
    if (recyclerView.getAdapter() == null) {
      recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
      recyclerView.setAdapter(dayClassAdapter);
    }
    dayClassAdapter.notifyDataSetChanged();
    //更新考试剩余时间信息
    try {
      List<ExamBean> examBeans = ScheduleData.getExamBeans();
      examBeans = CourseUtil.combineExam(examBeans);
      examBeans = CourseUtil.ridOfOutdatedExam(examBeans);
      if (examBeans.size() != 0) {
        showExam.setVisibility(View.VISIBLE);

        int n = TimeUtil.calcDayOffset(new Date(), examBeans.get(0).getDate());
        if (n > 1) {
          showExamDay.setText("您" + n + "天后有考试");
        } else if (n == 1) {
          showExamDay.setText("您明天有考试");
        } else {
          showExamDay.setText("您今天有考试");
        }
      } else {
        showExam.setVisibility(View.GONE);
      }
    } catch (Exception e) {
      showExam.setVisibility(View.GONE);
    }
  }

  private void setBackground(boolean setBackground) {
    View addStatus = view.findViewById(R.id.add_status);
    View titleBar = view.findViewById(R.id.title_bar);
    View syncInfo = view.findViewById(R.id.sync_info);
    if (setBackground) {
      titleBar.getBackground().setAlpha((int) singleSettingData.getTitleBarAlpha());
      addStatus.getBackground().setAlpha((int) singleSettingData.getTitleBarAlpha());
      syncInfo.getBackground().setAlpha((int) singleSettingData.getTitleBarAlpha());
    } else {
      titleBar.getBackground().setAlpha(255);
      addStatus.getBackground().setAlpha(255);
      syncInfo.getBackground().setAlpha(0);
    }
  }

  /**
   * 用户点击状态文字时的响应
   *
   * @param view 视图
   */
  @SuppressLint("NonConstantResourceId")
  @Override
  public void onClick(View view) {
    Intent intent;
    Intent webIntent = new Intent();
    webIntent.setAction("android.intent.action.VIEW");
    switch (view.getId()) {
      case R.id.day_class_hint:
        if ("去登录".contentEquals(textView.getText())) {
          MainActivity mainActivity = (MainActivity) getActivity();
          if (mainActivity != null) {
            mainActivity.onClick(3);
          }
          return;
        }
        autoUpdate.update();
        AppUtil.reportFunc(getContext(), "手动同步");
        break;
      case R.id.day_test_schedule:
        intent = new Intent(getContext(), ExamActivity.class);
        startActivity(intent);
        break;
      case R.id.day_url_bkjwtest:
        CommFunc.noLoginWebBKJWTest(getActivity());
        break;
      case R.id.day_test_scores:
        intent = new Intent(getContext(), ExamScoreNewActivity.class);
        startActivity(intent);
        break;
      case R.id.day_credits:
        intent = new Intent(getContext(), GradesActivity.class);
        startActivity(intent);
        break;
      default:
        ToastUtil.showToast(getContext(), "敬请期待！");
    }
  }

  public void updateText(String text) {
    textView.setText(text);
  }

  /**
   * 获取List<Schedule>类型的课表数据
   *
   * @return List<Schedule>类型的课表数据
   */
  private List<Schedule> getData() {
    List<Schedule> list = new ArrayList<>();
    if (settingData.getShowLibOnTable()) {
      list = ScheduleSupport.transform(ScheduleData.getLibBeans());
    }
    if (settingData.getShowExamOnTable()) {
      for (ExamBean examBean : CourseUtil.combineExam(ScheduleData.getExamBeans())) {
        if (examBean != null && examBean.getWeek() != 0) {
          list.add(examBean.getSchedule());
        }
      }
    }
    if (!ScheduleData.getCourseBeans().isEmpty()) {
      List<Schedule> courseList = ScheduleSupport.transform(ScheduleData.getCourseBeans());
      list.addAll(courseList);
    } else {
      list = new ArrayList<>();
    }
    for (CourseBean courseBean : ScheduleData.getUserCourseBeans()) {
      list.add(courseBean.getSchedule());
    }
    return list;
  }

  @Override
  public void onStart() {
    try {
      super.onStart();
      setBackground(BackgroundUtil.isSetBackground(requireContext()));
      initData();
      autoUpdate.updateView();
      updateView();
    } catch (Exception ignored) {
      ignored.printStackTrace();
    }
  }

  static class DayClassHandler extends Handler {
    WeakReference<DayClassFragment> weak;

    public DayClassHandler(@NonNull Looper looper, WeakReference<DayClassFragment> weakReference) {
      super(looper);
      this.weak = weakReference;
    }

    @Override
    public void handleMessage(@NonNull Message msg) {
      if (msg.what == 1) {
        if (weak.get() != null) {
          weak.get().updateView();
        }
        sendEmptyMessageDelayed(1, 60000);
      }
    }

  }

}